//! 字符串类型(文)的完整实现
//!
//! 设计原则：
//! - 支持Unicode字符处理
//! - 提供丰富的字符串操作方法
//! - 支持正则表达式和模式匹配
//! - 智能处理编码和格式转换

use crate::interpreter::method::{Method, MethodType};
use crate::interpreter::value::{Value, ValueData};
use regex::Regex;
use std::collections::HashMap;

/// 字符串类型(文)的内置方法实现
pub struct StringMethods;

impl StringMethods {
    /// 创建字符串类型的所有内置方法
    pub fn create_all_methods() -> HashMap<String, Method> {
        let mut methods = HashMap::new();

        // 基本属性方法
        methods.insert("长度".to_string(), Self::create_length_method());
        methods.insert("是否空".to_string(), Self::create_is_empty_method());
        methods.insert("字节长度".to_string(), Self::create_byte_length_method());

        // 大小写转换方法
        methods.insert("转大写".to_string(), Self::create_to_uppercase_method());
        methods.insert("转小写".to_string(), Self::create_to_lowercase_method());

        // 字符串搜索方法
        methods.insert("包含".to_string(), Self::create_contains_method());
        methods.insert("开始于".to_string(), Self::create_starts_with_method());
        methods.insert("结束于".to_string(), Self::create_ends_with_method());
        methods.insert("查找".to_string(), Self::create_find_method());
        methods.insert("查找最后".to_string(), Self::create_rfind_method());

        // 字符串操作
        methods.insert("分割".to_string(), Self::create_split_method());
        methods.insert("替换".to_string(), Self::create_replace_method());
        methods.insert("去除空格".to_string(), Self::create_trim_method());
        methods.insert("去除左边空格".to_string(), Self::create_trim_start_method());
        methods.insert("去除右边空格".to_string(), Self::create_trim_end_method());

        // 子字符串操作
        methods.insert("截取".to_string(), Self::create_substring_method());
        methods.insert("获取".to_string(), Self::create_char_at_method());
        methods.insert("重复".to_string(), Self::create_repeat_method());
        methods.insert("反转".to_string(), Self::create_reverse_method());

        // 格式化和转换
        methods.insert("填充左边".to_string(), Self::create_pad_start_method());
        methods.insert("填充右边".to_string(), Self::create_pad_end_method());
        methods.insert("格式化".to_string(), Self::create_format_method());

        // 正则表达式和模式匹配
        methods.insert("匹配".to_string(), Self::create_matches_method());
        methods.insert("查找匹配".to_string(), Self::create_find_matches_method());
        methods.insert(
            "替换匹配".to_string(),
            Self::create_replace_matches_method(),
        );

        // 编码和转换
        methods.insert("转数字".to_string(), Self::create_to_number_method());
        methods.insert("转列表".to_string(), Self::create_to_list_method());
        methods.insert("转字符列表".to_string(), Self::create_to_char_list_method());

        // 比较和排序
        methods.insert("比较".to_string(), Self::create_compare_method());
        methods.insert(
            "字典序比较".to_string(),
            Self::create_lexicographic_compare_method(),
        );

        methods
    }

    /// 创建长度方法（Unicode字符数）
    fn create_length_method() -> Method {
        Method::native(MethodType::Number, |args| {
            if let ValueData::String(s) = &args[0].data {
                Ok(Value::number(s.chars().count() as f64))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建是否空方法
    fn create_is_empty_method() -> Method {
        Method::native(MethodType::Boolean, |args| {
            if let ValueData::String(s) = &args[0].data {
                Ok(Value::boolean(s.is_empty()))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建字节长度方法（UTF-8字节数）
    fn create_byte_length_method() -> Method {
        Method::native(MethodType::Number, |args| {
            if let ValueData::String(s) = &args[0].data {
                Ok(Value::number(s.len() as f64))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建转大写方法
    fn create_to_uppercase_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let ValueData::String(s) = &args[0].data {
                Ok(Value::string(s.to_uppercase()))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建转小写方法
    fn create_to_lowercase_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let ValueData::String(s) = &args[0].data {
                Ok(Value::string(s.to_lowercase()))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建包含方法
    fn create_contains_method() -> Method {
        Method::native(MethodType::Boolean, |args| {
            if let (ValueData::String(s), ValueData::String(substr)) =
                (&args[0].data, &args[1].data)
            {
                Ok(Value::boolean(s.contains(substr)))
            } else {
                Err("包含方法需要字符串参数".to_string())
            }
        })
    }

    /// 创建开始于方法
    fn create_starts_with_method() -> Method {
        Method::native(MethodType::Boolean, |args| {
            if let (ValueData::String(s), ValueData::String(prefix)) =
                (&args[0].data, &args[1].data)
            {
                Ok(Value::boolean(s.starts_with(prefix)))
            } else {
                Err("开始于方法需要字符串参数".to_string())
            }
        })
    }

    /// 创建结束于方法
    fn create_ends_with_method() -> Method {
        Method::native(MethodType::Boolean, |args| {
            if let (ValueData::String(s), ValueData::String(suffix)) =
                (&args[0].data, &args[1].data)
            {
                Ok(Value::boolean(s.ends_with(suffix)))
            } else {
                Err("结束于方法需要字符串参数".to_string())
            }
        })
    }

    /// 创建查找方法
    fn create_find_method() -> Method {
        Method::native(MethodType::Number, |args| {
            if let (ValueData::String(s), ValueData::String(pattern)) =
                (&args[0].data, &args[1].data)
            {
                match s.find(pattern) {
                    Some(index) => Ok(Value::number(index as f64)),
                    None => Ok(Value::number(-1.0)), // 未找到返回-1
                }
            } else {
                Err("查找方法需要字符串参数".to_string())
            }
        })
    }

    /// 创建查找最后方法
    fn create_rfind_method() -> Method {
        Method::native(MethodType::Number, |args| {
            if let (ValueData::String(s), ValueData::String(pattern)) =
                (&args[0].data, &args[1].data)
            {
                match s.rfind(pattern) {
                    Some(index) => Ok(Value::number(index as f64)),
                    None => Ok(Value::number(-1.0)), // 未找到返回-1
                }
            } else {
                Err("查找最后方法需要字符串参数".to_string())
            }
        })
    }

    /// 创建分割方法
    fn create_split_method() -> Method {
        Method::native(MethodType::List, |args| {
            if let (ValueData::String(s), ValueData::String(delimiter)) =
                (&args[0].data, &args[1].data)
            {
                let parts: Vec<Value> = s
                    .split(delimiter)
                    .map(|part| Value::string(part.to_string()))
                    .collect();
                Ok(Value::list(parts))
            } else {
                Err("分割方法需要字符串参数".to_string())
            }
        })
    }

    /// 创建替换方法
    fn create_replace_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let (ValueData::String(s), ValueData::String(old), ValueData::String(new)) =
                (&args[0].data, &args[1].data, &args[2].data)
            {
                Ok(Value::string(s.replace(old, new)))
            } else {
                Err("替换方法需要三个字符串参数".to_string())
            }
        })
    }

    /// 创建去除空格方法
    fn create_trim_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let ValueData::String(s) = &args[0].data {
                Ok(Value::string(s.trim().to_string()))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建去除左边空格方法
    fn create_trim_start_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let ValueData::String(s) = &args[0].data {
                Ok(Value::string(s.trim_start().to_string()))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建去除右边空格方法
    fn create_trim_end_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let ValueData::String(s) = &args[0].data {
                Ok(Value::string(s.trim_end().to_string()))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建截取方法
    fn create_substring_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let (ValueData::String(s), ValueData::Number(start), ValueData::Number(end)) =
                (&args[0].data, &args[1].data, &args[2].data)
            {
                let start_idx = *start as usize;
                let end_idx = *end as usize;
                let chars: Vec<char> = s.chars().collect();

                if start_idx > chars.len() || end_idx > chars.len() || start_idx > end_idx {
                    Ok(Value::string("".to_string()))
                } else {
                    let substring: String = chars[start_idx..end_idx].iter().collect();
                    Ok(Value::string(substring))
                }
            } else {
                Err("截取方法需要字符串和两个数字参数".to_string())
            }
        })
    }

    /// 创建获取字符方法
    fn create_char_at_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let (ValueData::String(s), ValueData::Number(index)) = (&args[0].data, &args[1].data)
            {
                let chars: Vec<char> = s.chars().collect();
                let idx = *index as usize;

                if idx >= chars.len() {
                    Ok(Value::string("".to_string()))
                } else {
                    Ok(Value::string(chars[idx].to_string()))
                }
            } else {
                Err("获取方法需要字符串和数字参数".to_string())
            }
        })
    }

    /// 创建重复方法
    fn create_repeat_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let (ValueData::String(s), ValueData::Number(count)) = (&args[0].data, &args[1].data)
            {
                let repeat_count = *count as usize;
                if repeat_count == 0 {
                    Ok(Value::string("".to_string()))
                } else {
                    Ok(Value::string(s.repeat(repeat_count).to_string()))
                }
            } else {
                Err("重复方法需要字符串和数字参数".to_string())
            }
        })
    }

    /// 创建反转方法
    fn create_reverse_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let ValueData::String(s) = &args[0].data {
                let reversed: String = s.chars().rev().collect();
                Ok(Value::string(reversed))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建填充左边方法
    fn create_pad_start_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let (
                ValueData::String(s),
                ValueData::Number(target_length),
                ValueData::String(pad_string),
            ) = (&args[0].data, &args[1].data, &args[2].data)
            {
                let target_len = *target_length as usize;
                let current_len = s.chars().count();

                if current_len >= target_len {
                    Ok(Value::string(s.to_string()))
                } else {
                    let pad_len = target_len - current_len;
                    let pad_chars: Vec<char> = pad_string.chars().collect();
                    let mut result = String::new();

                    // 计算需要多少个填充字符
                    let mut remaining = pad_len;
                    while remaining > 0 {
                        for &ch in &pad_chars {
                            if remaining == 0 {
                                break;
                            }
                            result.push(ch);
                            remaining -= 1;
                        }
                    }

                    result.push_str(s);
                    Ok(Value::string(result))
                }
            } else {
                Err("填充左边方法需要字符串、数字和字符串参数".to_string())
            }
        })
    }

    /// 创建填充右边方法
    fn create_pad_end_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let (
                ValueData::String(s),
                ValueData::Number(target_length),
                ValueData::String(pad_string),
            ) = (&args[0].data, &args[1].data, &args[2].data)
            {
                let target_len = *target_length as usize;
                let current_len = s.chars().count();

                if current_len >= target_len {
                    Ok(Value::string(s.to_string()))
                } else {
                    let pad_len = target_len - current_len;
                    let pad_chars: Vec<char> = pad_string.chars().collect();
                    let mut result = s.to_string();

                    // 计算需要多少个填充字符
                    let mut remaining = pad_len;
                    while remaining > 0 {
                        for &ch in &pad_chars {
                            if remaining == 0 {
                                break;
                            }
                            result.push(ch);
                            remaining -= 1;
                        }
                    }

                    Ok(Value::string(result))
                }
            } else {
                Err("填充右边方法需要字符串、数字和字符串参数".to_string())
            }
        })
    }

    /// 创建格式化方法（简单的占位符替换）
    fn create_format_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let ValueData::String(template) = &args[0].data {
                let mut result = template.clone();

                // 简单的占位符替换：{0}, {1}, {2}...
                for (i, arg) in args.iter().skip(1).enumerate() {
                    let placeholder = format!("{{{}}}", i);
                    let value_str = match &arg.data {
                        ValueData::Number(n) => n.to_string(),
                        ValueData::String(s) => s.clone(),
                        ValueData::Boolean(b) => b.to_string(),
                        ValueData::Null => "无".to_string(),
                        _ => "未知".to_string(),
                    };
                    result = result.replace(&placeholder, &value_str);
                }

                Ok(Value::string(result))
            } else {
                Err("格式化方法需要字符串模板".to_string())
            }
        })
    }

    /// 创建匹配方法（正则表达式）
    fn create_matches_method() -> Method {
        Method::native(MethodType::Boolean, |args| {
            if let (ValueData::String(s), ValueData::String(pattern)) =
                (&args[0].data, &args[1].data)
            {
                match Regex::new(pattern) {
                    Ok(re) => Ok(Value::boolean(re.is_match(s))),
                    Err(e) => Err(format!("无效的正则表达式: {}", e)),
                }
            } else {
                Err("匹配方法需要两个字符串参数".to_string())
            }
        })
    }

    /// 创建查找匹配方法（返回所有匹配项）
    fn create_find_matches_method() -> Method {
        Method::native(MethodType::List, |args| {
            if let (ValueData::String(s), ValueData::String(pattern)) =
                (&args[0].data, &args[1].data)
            {
                match Regex::new(pattern) {
                    Ok(re) => {
                        let matches: Vec<Value> = re
                            .find_iter(s)
                            .map(|mat| Value::string(mat.as_str().to_string()))
                            .collect();
                        Ok(Value::list(matches))
                    }
                    Err(e) => Err(format!("无效的正则表达式: {}", e)),
                }
            } else {
                Err("查找匹配方法需要两个字符串参数".to_string())
            }
        })
    }

    /// 创建替换匹配方法（正则表达式替换）
    fn create_replace_matches_method() -> Method {
        Method::native(MethodType::String, |args| {
            if let (
                ValueData::String(s),
                ValueData::String(pattern),
                ValueData::String(replacement),
            ) = (&args[0].data, &args[1].data, &args[2].data)
            {
                match Regex::new(pattern) {
                    Ok(re) => Ok(Value::string(re.replace_all(s, replacement).to_string())),
                    Err(e) => Err(format!("无效的正则表达式: {}", e)),
                }
            } else {
                Err("替换匹配方法需要三个字符串参数".to_string())
            }
        })
    }

    /// 创建转数字方法
    fn create_to_number_method() -> Method {
        Method::native(MethodType::Number, |args| {
            if let ValueData::String(s) = &args[0].data {
                match s.parse::<f64>() {
                    Ok(n) => Ok(Value::number(n)),
                    Err(_) => Err(format!("无法将字符串 '{}' 转换为数字", s)),
                }
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建转列表方法（按字符分割）
    fn create_to_list_method() -> Method {
        Method::native(MethodType::List, |args| {
            if let ValueData::String(s) = &args[0].data {
                let chars: Vec<Value> = s.chars().map(|ch| Value::string(ch.to_string())).collect();
                Ok(Value::list(chars))
            } else {
                Err("不是字符串类型".to_string())
            }
        })
    }

    /// 创建转字符列表方法（按字符分割，与转列表相同）
    fn create_to_char_list_method() -> Method {
        Self::create_to_list_method() // 功能相同
    }

    /// 创建比较方法（相等性比较）
    fn create_compare_method() -> Method {
        Method::native(MethodType::Boolean, |args| {
            if let (ValueData::String(s1), ValueData::String(s2)) = (&args[0].data, &args[1].data) {
                Ok(Value::boolean(s1 == s2))
            } else {
                Err("比较方法需要两个字符串参数".to_string())
            }
        })
    }

    /// 创建字典序比较方法
    fn create_lexicographic_compare_method() -> Method {
        Method::native(MethodType::Number, |args| {
            if let (ValueData::String(s1), ValueData::String(s2)) = (&args[0].data, &args[1].data) {
                match s1.cmp(s2) {
                    std::cmp::Ordering::Less => Ok(Value::number(-1.0)),
                    std::cmp::Ordering::Equal => Ok(Value::number(0.0)),
                    std::cmp::Ordering::Greater => Ok(Value::number(1.0)),
                }
            } else {
                Err("字典序比较方法需要两个字符串参数".to_string())
            }
        })
    }
}
